#include "Triangle.h"
#include "DirectX\Buffer.h"
#include "NeroEngine\NPlatform.h"
#include "DirectX\Color.h"
#include "NeroCore\NMemoryManager.h"

using namespace Graphics;

#define SIZE 2.0f

Triangle::Triangle(void)
	:RenderableEntity(),
	mVertexCount(0),
	mIndexCount(0)
{
}

Triangle::~Triangle(void)
{
}

void Triangle::Initialize()
{
	RenderableEntity::Initialize();

	mVertexBuffer = MY_NEW(Memory::HID_Rendering,"Triangle VBuffer") Graphics::Buffer();
	mIndexBuffer = MY_NEW(Memory::HID_Rendering,"Triangle IBuffer") Graphics::Buffer();
#ifdef DX_11
	mVertexCount = 3;
	mIndexCount = mVertexCount;

	Graphics::D3DDevice* nDevice = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();
	VertexType* vertices  = new VertexType[mVertexCount];

	vertices[0].Position = D3DXVECTOR3(-SIZE, -SIZE, 0.0f);  // Bottom left.
	vertices[0].Color = Colors::Green;
	vertices[0].Texture = D3DXVECTOR2(0.0f, 1.0f);
	vertices[0].normal = D3DXVECTOR3(0.0f, 0.0f, -1.0f);

	vertices[1].Position = D3DXVECTOR3(0.0f, SIZE, 0.0f);  // Top middle.
	vertices[1].Color = Colors::Green;
	vertices[1].Texture = D3DXVECTOR2(0.5f, 0.0f);
	vertices[1].normal = D3DXVECTOR3(0.0f, 0.0f, -1.0f);

	vertices[2].Position = D3DXVECTOR3(SIZE, -SIZE, 0.0f);  // Bottom right.
	vertices[2].Color = Colors::Green;
	vertices[2].Texture = D3DXVECTOR2(1.0f, 1.0f);
	vertices[2].normal = D3DXVECTOR3(0.0f, 0.0f, -1.0f);

	unsigned long* indices = new unsigned long[mIndexCount];

	// Load the index array with data.
	indices[0] = 0;  // Bottom left.
	indices[1] = 1;  // Top middle.
	indices[2] = 2;  // Bottom right.

	mVertexBuffer->Initialize(sizeof(VertexType), vertices, mVertexCount, BufferType::VertexBuffer);

	mIndexBuffer->Initialize(sizeof(unsigned long), indices, mVertexCount, BufferType::IndexBuffer);

	delete [] vertices;
	vertices = NULL;

	delete [] indices;
	indices = NULL;

#elif defined( DX_9 )
	Graphics::D3DDevice* nDevice = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();
	LPDIRECT3DDEVICE9 device = nDevice->GetDevice();
	mBuffer->Initialize(device, 3);
#endif	
	mEnabled = true;
}

void Triangle::Render()
{
	if(mEnabled)
	{
#ifdef DX_11
		unsigned int stride = sizeof(VertexType);
		unsigned int offset = 0;

		Graphics::D3DDevice* nDevice = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();
	
		mVertexBuffer->Render(stride, offset);
		
		mIndexBuffer->Render(stride, offset);
		// Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
		nDevice->GetDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
#elif defined( DX_9 )
		HRESULT result;
		CUSTOMVERTEX vertices[] =
		{
			{ 0.0f, 10.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255), },
			{ 5.0f,  0.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), },
			{ -5.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), },
		};

		Graphics::D3DDevice* nDevice = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();
		LPDIRECT3DDEVICE9 device = nDevice->GetDevice();

		mBuffer->Lock();
		memcpy(mBuffer->GetMemoryPointer(), vertices, sizeof(vertices));
		mBuffer->Unlock();
		mBuffer->Render(device);

		result = device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
		CHECK(result)
#endif		
	}
}

int Triangle::GetIndexCount()
{
	return mIndexCount;
}

int Triangle::GetInstanceCount()
{
	return 1;
}